﻿// 1590：恨 7 不成妻.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//


/*
http://ybt.ssoier.cn:8088/problem_show.php?pid=1590
https://www.acwing.com/problem/content/description/1088/
https://loj.ac/p/10168

单身！
依然单身！
吉哥依然单身！
DS 级码农吉哥依然单身！

所以，他平生最恨情人节，不管是 214还是 77，他都讨厌！
吉哥观察了 214 和 77 这两个数，发现：
2+1+4=7
7+7=7×2
77=7×11
最终，他发现原来这一切归根到底都是因为和 77 有关！所以，他现在甚至讨厌一切和 7 有关的数！
什么样的数和 7 有关呢？如果一个整数符合下面三个条件之一，那么我们就说这个整数和 7 有关：
整数中某一位是 7；

整数的每一位加起来的和是 7 的整数倍；

这个整数是 7 的整数倍。

现在问题来了：吉哥想知道在一定区间内和 7 无关的数字的平方和。

【输入】
输入数据的第一行是测试数据组数 T，然后接下来的 T 行表示 T 组测试数据。
每组数据在一行内包含两个正整数 L,R。

【输出】
对于每组数据，请计算 [L,R] 中和 7无关的数字的平方和，并将结果对 109+7取模后输出。

【输入样例】
3
1 9
10 11
17 17
【输出样例】
236
221
0

数据范围
1≤T≤50,1≤L≤R≤10^18
*/

#include <iostream>
#include <vector>

using  namespace std;

typedef long long LL;
const int N = 20, P = 1e9 + 7;

struct F {
	int s0, s1, s2;
}f[N][10][7][7];

int power7[N], power9[N];

//mod 函数 避免出现负数
int mod(LL x, int y) {
	return (x % y + y) % y;
}

void init() {
	for (int i = 0; i <= 9; i++) {
		if (i == 7) continue;
		auto& v = f[1][i][i % 7][i % 7];
		v.s0++;
		v.s1 += i;
		v.s2 += i * i;
	}

	LL power = 10;
	for (int i = 2; i < N; i++, power *= 10) {
		for (int j = 0; j <= 9; j++) {
			if (j == 7) continue;
			for(int a =0;a<7;a++) 
				for(int b =0;b<7;b++)
					for (int k = 0; k <= 9; k++) {
						if (k == 7) continue;
						auto& v1 = f[i][j][a][b], & v2 = f[i - 1][k][mod(a - j * (power % 7), 7)][mod(b - j, 7)];
						v1.s0 = (v1.s0 + v2.s0) % P;
						v1.s1 = (v1.s1 + j * (power % P) % P * v2.s0 + v2.s1) % P;
						v1.s2 = (v1.s2 +
							j * j * (power % P) % P * (power % P) % P * v2.s0 % P +
							2 * j * (power % P) % P * v2.s1 % P +
							v2.s2) % P;
					}
		}
	}

	power7[0] = power9[0] = 1;
	for (int i = 1; i < N; i++) {
		power7[i] = power7[i - 1] * 10 % 7;
		power9[i] = power9[i - 1] * 10ll % P;
	}
}

F get(int i, int j, int a, int b) {
	int s0 = 0, s1 = 0, s2 = 0;
	for(int x = 0;x<7;x++)
		for (int y = 0; y < 7; y++) {
			if (x == a || y == b) continue;
			auto v = f[i][j][x][y];
			s0 = (s0 + v.s0) % P;
			s1 = (s1 + v.s1) % P;
			s2 = (s2 + v.s2) % P;
		}
	return { s0,s1,s2 };
}

int dp(LL n) {
	if (!n) return 0;

	LL backup_n = n % P;
	vector<int> nums;
	while (n) nums.push_back(n % 10), n /= 10;

	int res = 0;
	LL last_a = 0, last_b = 0;
	for (int i = nums.size() - 1; i >= 0; i--) {
		int x = nums[i];
		for (int j = 0; j < x; j++) {
			if (j == 7) continue;
			int a = mod(-last_a % 7 * power7[i + 1], 7);
			int b = mod(-last_b, 7);

			auto v = get(i + 1, j, a, b);
			res = (res +
				(last_a % P) * (last_a % P) % P * power9[i + 1] % P * power9[i + 1] % P * v.s0 % P +
				2 * (last_a % P) % P * power9[i + 1] % P * v.s1 % P + v.s2) % P;
		}

		if (x == 7) break;
		last_a = last_a * 10 + x;
		last_b += x;

		if (!i && last_a % 7 && last_b % 7) res = (res + backup_n * backup_n) % P;
	}
	
	return res;
}


int main()
{
	init();
	int T;
	cin >> T;
	while (T--) {
		LL l, r;
		cin >> l >> r;
		cout << mod(dp(r) - dp(l - 1), P) << endl;
	}


	return 0;
}

 
/*
* //更简洁的记忆化搜索代码
#include <iostream>
#include <cstring>

using namespace std;
typedef long long LL;

const int N = 20;
const LL mod = 1e9 + 7;

LL a[N]; //记录拆分后的每位数
LL base[N];	//预处理10的幂次方在mod后的结果

struct Node {
	LL s0;	//满足条件的个数
	LL s1;	//满足条件的数字和
	LL s2;	//满足条件的数字平方和
}f[N][7][7];


//维度1: u 数位位置索引
//维度2: sum 前面数位上的值和 mod7
//维度3：pre 前面数字和 mod7
//op:是否超过输入数字改为的值 未超过 后面的数值可以取0~9 ,等于则下一位[u-1]的取值范围是0~~a[u-1]

Node dfs(int u, int sum, int pre, bool op) {
	//u==0  根据sum 不是7的倍数 且  pre 不是7的倍数，则数合法, 返回个数1,否则返回0
	if (u == 0) {
		if (sum && pre) return { 1,0,0 };
		return { 0,0,0 };
	}
	//记忆化
	if (!op && f[u][sum][pre].s0 != -1) return f[u][sum][pre];
	//根据op判断可以取值的上界
	int up = op ? a[u] : 9;


	struct Node ans = { 0,0,0 };
	for (int i = 0; i <= up; i++) {
		if (i == 7) continue;
		struct Node ret = dfs(u - 1, (sum + i) % 7, (pre * 10 + i) % 7, op && (i == up));
		ans.s0 = (ans.s0 + ret.s0) % mod;
		//ans.s1 = (ans.s1 + ret.s0 * i % mod * base[u - 1] % mod + ret.s1) % mod;
		ans.s1 = (ans.s1 + i * base[u - 1] % mod * ret.s0 % mod + ret.s1) % mod;
		// 汇集数字平方和
		ans.s2 = (ans.s2 + i * base[u - 1] % mod * i % mod * base[u - 1] % mod * ret.s0 % mod) % mod;
		//ans.s2 = (ans.s2 + 2 * i % mod * base[u - 1] % mod * ret.s1 % mod + ret.s2) % mod;
		ans.s2 = (ans.s2 + 2 * i * base[u - 1] % mod * ret.s1 % mod + ret.s2) % mod;
	}

	if (!op) f[u][sum][pre] = ans;



	return ans;
}




LL calc(LL x) {
	int idx = 0;
	while (x != 0) {
		a[++idx] = x % 10;
		x /= 10;
	}

	return dfs(idx, 0, 0, true).s2;
}


int main()
{
	memset(f, -1, sizeof f);

	// 预处理出10的幂次方【因为涉及到取模，要不这玩意还用预处理？】
	base[0] = 1;
	for (int i = 1; i < N; i++) base[i] = base[i - 1] * 10 % mod;

	int T; cin >> T;
	while (T--) {
		LL l, r; cin >> l >> r;
		cout << (calc(r) - calc(l - 1) + mod) % mod << endl;
	}

	return 0;
}
*/